{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Extract Data from Financial Reports - with Citations and Reasoning\n",
    "\n",
    "Given complex files like financial reports, contracts, invoices etc, Llama Extract allows you to make use of an LLM to extract the information relevant to you, in a structured format.\n",
    "\n",
    "In this example, we'll be using [LlamaExtract](https://docs.cloud.llamaindex.ai/llamaextract/getting_started?utm_campaign=extract&utm_medium=recipe) to extract structured data from an SEC filing (specifically, the filing by Nvidia for fiscal year 2025).\n",
    "\n",
    "On top of simple data extraction, we'll ask our extraction agent to provide citations and reasoning for each extracted field. This allows us to:\n",
    "- Confirm  the accuracy of the extracted field\n",
    "- Understand the reasoning behind why the LLM extracted a given piece of information\n",
    "- This last point allows us an opportunity to adjust the system prompt or field descriptions and improve on results where needed.\n",
    "\n",
    "\n",
    "The example we go through below is also replicable within Llama Cloud as well, where you will also be able to pick between a number of pre-defined schemas, instead of building your own."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install llama-cloud-services"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Connect to Llama Cloud\n",
    "\n",
    "To get started, make sure you provide your [Llama Cloud](https://cloud.llamaindex.ai?utm_campaign=extract&utm_medium=recipe) API key."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Enter your Llama Cloud API Key: ··········\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "from getpass import getpass\n",
    "\n",
    "if \"LLAMA_CLOUD_API_KEY\" not in os.environ:\n",
    "    os.environ[\"LLAMA_CLOUD_API_KEY\"] = getpass(\"Enter your Llama Cloud API Key: \")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Extract Data with Llama Extract Agent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "No project_id provided, fetching default project.\n"
     ]
    }
   ],
   "source": [
    "from llama_cloud_services import LlamaExtract\n",
    "\n",
    "# Optionally, provide your project id, if not, it will use the 'Default' project\n",
    "llama_extract = LlamaExtract()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Provide Your Custom Schema\n",
    "\n",
    "When using LlamaExtract via the API, you provide your own schema that describes what you want extracted from files and data provided to your agent. Here, we are essentially building an SEC filings extraction agent."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pydantic import BaseModel, Field\n",
    "from enum import Enum\n",
    "\n",
    "\n",
    "class FilingType(str, Enum):\n",
    "    ten_k = \"10 K\"\n",
    "    ten_q = \"10-Q\"\n",
    "    ten_ka = \"10-K/A\"\n",
    "    ten_qa = \"10-Q/A\"\n",
    "\n",
    "\n",
    "class FinancialReport(BaseModel):\n",
    "    company_name: str = Field(description=\"The name of the company\")\n",
    "    description: str = Field(\n",
    "        description=\"Short description of the filing and what it contains\"\n",
    "    )\n",
    "    filing_type: FilingType = Field(description=\"Type of SEC filing\")\n",
    "    filing_date: str = Field(description=\"Date when filing was submitted to SEC\")\n",
    "    fiscal_year: int = Field(description=\"Fiscal year\")\n",
    "    unit: str = Field(\n",
    "        description=\"Unit of financial figures (thousands, millions, etc.)\"\n",
    "    )\n",
    "    revenue: int = Field(description=\"Total revenue for period\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Set Up Citations and Reasoning\n",
    "\n",
    "Optionally, we can set the `ExtractConfig` to extract citations for each field the agent extracts. These cications will cite the specific pages and sections of the file from which a given field was extractedd.\n",
    "\n",
    "By setting `use_reasoning` to True, we als ask the agent to do an additional reasoning step, explaining why a given field was extracted."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from llama_cloud.types import ExtractConfig, ExtractMode\n",
    "\n",
    "config = ExtractConfig(\n",
    "    use_reasoning=True, cite_sources=True, extraction_mode=ExtractMode.MULTIMODAL\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.11/dist-packages/llama_cloud_services/extract/extract.py:127: ExperimentalWarning: `use_reasoning` is an experimental feature. Results will be available in the `extraction_metadata` field for the extraction run.\n",
      "  warnings.warn(\n",
      "/usr/local/lib/python3.11/dist-packages/llama_cloud_services/extract/extract.py:133: ExperimentalWarning: `cite_sources` is an experimental feature. This may greatly increase the size of the response, and slow down the extraction. Results will be available in the `extraction_metadata` field for the extraction run.\n",
      "  warnings.warn(\n"
     ]
    }
   ],
   "source": [
    "agent = llama_extract.create_agent(\n",
    "    name=\"filing-parser\", data_schema=FinancialReport, config=config\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Demo Time - Download a PDF and Extract Data with Citations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "PDF downloaded successfully.\n"
     ]
    }
   ],
   "source": [
    "import requests\n",
    "\n",
    "url = \"https://raw.githubusercontent.com/run-llama/llama_cloud_services/refs/heads/main/examples/extract/data/sec_filings/nvda_10k.pdf\"\n",
    "\n",
    "response = requests.get(url)\n",
    "\n",
    "if response.status_code == 200:\n",
    "    with open(\"/content/nvda_10k.pdf\", \"wb\") as f:\n",
    "        f.write(response.content)\n",
    "    print(\"PDF downloaded successfully.\")\n",
    "else:\n",
    "    print(f\"Failed to download. Status code: {response.status_code}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Uploading files: 100%|██████████| 1/1 [00:00<00:00,  1.83it/s]\n",
      "Creating extraction jobs: 100%|██████████| 1/1 [00:00<00:00,  4.38it/s]\n",
      "Extracting files: 100%|██████████| 1/1 [02:03<00:00, 123.40s/it]\n"
     ]
    }
   ],
   "source": [
    "filing_info = agent.extract(\"/content/nvda_10k.pdf\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'company_name': 'NVIDIA Corporation',\n",
       " 'description': \"The filing provides a detailed overview of NVIDIA's business as a full-stack computing infrastructure company, discusses various technologies including digital avatars and autonomous vehicles, outlines numerous risk factors affecting operations such as supply chain issues and geopolitical tensions, and describes employee stock purchase plans and related compliance requirements.\",\n",
       " 'filing_type': '10 K',\n",
       " 'filing_date': 'February 26, 2025',\n",
       " 'fiscal_year': 2025,\n",
       " 'unit': 'millions',\n",
       " 'revenue': 130497}"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "filing_info.data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Inspect Citations and Reasoning"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'field_metadata': {'company_name': {'reasoning': 'VERBATIM EXTRACTION',\n",
       "   'citation': [{'page': 1, 'matching_text': 'NVIDIA CORPORATION'},\n",
       "    {'page': 2, 'matching_text': 'NVIDIA Corporation'},\n",
       "    {'page': 3,\n",
       "     'matching_text': 'All references to \"NVIDIA,\" \"we,\" \"us,\" \"our,\" or the \"Company\" mean NVIDIA Corporation and its subsidiaries.'},\n",
       "    {'page': 35,\n",
       "     'matching_text': 'Comparison of 5 Year Cumulative Total Return* Among NVIDIA Corporation'},\n",
       "    {'page': 49,\n",
       "     'matching_text': 'To the Board of Directors and Shareholders of NVIDIA Corporation'},\n",
       "    {'page': 90, 'matching_text': 'NVIDIA Corporation'},\n",
       "    {'page': 119,\n",
       "     'matching_text': '*\"Company\"* means NVIDIA Corporation, a Delaware corporation.'},\n",
       "    {'page': 126,\n",
       "     'matching_text': 'Annual Report on Form 10-K of NVIDIA Corporation'}]},\n",
       "  'filing_type': {'reasoning': \"VERBATIM EXTRACTION from multiple sources confirming the filing type as '10 K'.\",\n",
       "   'citation': [{'page': 1, 'matching_text': 'FORM 10-K'},\n",
       "    {'page': 2, 'matching_text': 'Item 16. | Form 10-K Summary'},\n",
       "    {'page': 3,\n",
       "     'matching_text': 'This Annual Report on Form 10-K contains forward-looking statements...'},\n",
       "    {'page': 13, 'matching_text': 'this Annual Report on Form 10-K'},\n",
       "    {'page': 15, 'matching_text': 'this Annual Report on Form 10-K'},\n",
       "    {'page': 32,\n",
       "     'matching_text': 'Annual Report on Form 10-K, which information is hereby incorporated by reference.'},\n",
       "    {'page': 36, 'matching_text': 'this Annual Report on Form 10-K'},\n",
       "    {'page': 43,\n",
       "     'matching_text': 'Annual Report on Form 10-K for additional information'},\n",
       "    {'page': 45, 'matching_text': 'Annual Report on Form 10-K'},\n",
       "    {'page': 46, 'matching_text': 'this Annual Report on Form 10-K'},\n",
       "    {'page': 62, 'matching_text': 'Annual Report on Form 10-K'},\n",
       "    {'page': 83,\n",
       "     'matching_text': 'Restated Certificate of Incorporation | 10-K'},\n",
       "    {'page': 84, 'matching_text': 'Item 16. Form 10-K Summary'},\n",
       "    {'page': 126, 'matching_text': 'which appears in this Form 10-K'},\n",
       "    {'page': 127, 'matching_text': 'Annual Report on Form 10-K'},\n",
       "    {'page': 128, 'matching_text': 'Annual Report on Form 10-K'},\n",
       "    {'page': 129, 'matching_text': \"The Company's Annual Report on Form 10-K\"},\n",
       "    {'page': 130,\n",
       "     'matching_text': \"The Company's Annual Report on Form 10-K for the year ended January 26, 2025\"}]},\n",
       "  'fiscal_year': {'reasoning': 'The fiscal year ended January 26, 2025, indicates the fiscal year is 2025. Additionally, multiple references throughout the text confirm the fiscal year 2025 in various contexts.',\n",
       "   'citation': [{'page': 1,\n",
       "     'matching_text': 'For the fiscal year ended January 26, 2025'},\n",
       "    {'page': 6,\n",
       "     'matching_text': 'In fiscal year 2025, we launched the NVIDIA Blackwell architecture'},\n",
       "    {'page': 12, 'matching_text': 'fiscal year 2025'},\n",
       "    {'page': 17,\n",
       "     'matching_text': 'our gross margins in the second quarter of fiscal year 2025 were negatively impacted'},\n",
       "    {'page': 20,\n",
       "     'matching_text': 'we generated 53% of our revenue in fiscal year 2025 from sales outside the United States.'},\n",
       "    {'page': 23,\n",
       "     'matching_text': 'For fiscal year 2025, an indirect customer which primarily purchases our products through system integrators...'},\n",
       "    {'page': 33,\n",
       "     'matching_text': 'In fiscal year 2025, we repurchased 310 million shares of our common stock for $34.0 billion.'},\n",
       "    {'page': 37,\n",
       "     'matching_text': 'Our Data Center revenue in China grew in fiscal year 2025.'},\n",
       "    {'page': 44,\n",
       "     'matching_text': 'Cash provided by operating activities increased in fiscal year 2025 compared to fiscal year 2024'},\n",
       "    {'page': 57,\n",
       "     'matching_text': 'Fiscal years 2025, 2024 and 2023 were all 52-week years.'},\n",
       "    {'page': 65,\n",
       "     'matching_text': 'Beginning in the second quarter of fiscal year 2025'},\n",
       "    {'page': 69, 'matching_text': 'In the fourth quarter of fiscal year 2025'},\n",
       "    {'page': 78,\n",
       "     'matching_text': 'Depreciation and amortization expense attributable to our Compute and Networking segment for fiscal years 2025'},\n",
       "    {'page': 129, 'matching_text': 'for the year ended January 26, 2025'}]},\n",
       "  'description': {'reasoning': 'The extracted data combines multiple descriptions from the source text, ensuring no duplication while maintaining the order and context of the information. Each section of the filing is summarized to reflect the key points without losing the essence of the original text.',\n",
       "   'citation': [{'page': 4,\n",
       "     'matching_text': 'NVIDIA is now a full-stack computing infrastructure company with data-center-scale offerings that are reshaping industry.'},\n",
       "    {'page': 8,\n",
       "     'matching_text': 'a suite of technologies that help developers bring digital avatars to life with generative Al...autonomous vehicles, or AV, and electric vehicles, or EV, is revolutionizing the transportation industry...Our worldwide sales and marketing strategy is key to achieving our objective of providing markets with our high-performance and efficient computing platforms and software.'},\n",
       "    {'page': 14, 'matching_text': 'Risk Factors Summary'},\n",
       "    {'page': 16,\n",
       "     'matching_text': 'Risks Related to Demand, Supply, and Manufacturing\\n\\nLong manufacturing lead times and uncertain supply and component availability...'},\n",
       "    {'page': 18,\n",
       "     'matching_text': 'cryptocurrency mining, on demand for our products. Volatility in the cryptocurrency market, including new compute technologies...'},\n",
       "    {'page': 21,\n",
       "     'matching_text': 'supply-chain attacks or other business disruptions. We cannot guarantee that third parties and infrastructure in our supply chain...'},\n",
       "    {'page': 22,\n",
       "     'matching_text': 'We are monitoring the impact of the geopolitical conflict in and around Israel on our operations... Climate change may have a long-term impact on our business.'},\n",
       "    {'page': 25,\n",
       "     'matching_text': 'We are subject to complex laws, rules, regulations, and political and other actions, including restrictions on the export of our products, which may adversely impact our business.'},\n",
       "    {'page': 28,\n",
       "     'matching_text': 'Our competitive position has been harmed by the existing export controls, and our competitive position and future results may be further harmed'},\n",
       "    {'page': 29,\n",
       "     'matching_text': 'restrictions imposed by the Chinese government on the duration of gaming activities and access to games may adversely affect our Gaming revenue'},\n",
       "    {'page': 29,\n",
       "     'matching_text': 'our business depends on our ability to receive consistent and reliable supply from our overseas partners, especially in Taiwan and South Korea'},\n",
       "    {'page': 29,\n",
       "     'matching_text': 'Increased scrutiny from shareholders, regulators and others regarding our corporate sustainability practices could result in additional costs'},\n",
       "    {'page': 29,\n",
       "     'matching_text': 'Concerns relating to the responsible use of new and evolving technologies, such as Al, in our products and services may result in reputational or financial harm'},\n",
       "    {'page': 31,\n",
       "     'matching_text': 'Data protection laws around the world are quickly changing and may be interpreted and applied in an increasingly stringent fashion...'}]},\n",
       "  'filing_date': {'reasoning': 'The filing date is consistently mentioned as February 26, 2025 across multiple entries, making it the most reliable date for the filing.',\n",
       "   'citation': [{'page': 51, 'matching_text': 'February 26, 2025'},\n",
       "    {'page': 86, 'matching_text': 'on February 26, 2025.'},\n",
       "    {'page': 87, 'matching_text': 'February 26, 2025'},\n",
       "    {'page': 126, 'matching_text': 'our report dated February 26, 2025'},\n",
       "    {'page': 127, 'matching_text': 'Date: February 26, 2025'},\n",
       "    {'page': 128, 'matching_text': 'Date: February 26, 2025'},\n",
       "    {'page': 129, 'matching_text': 'Date: February 26, 2025'},\n",
       "    {'page': 130, 'matching_text': 'Date: February 26, 2025'}]},\n",
       "  'unit': {'reasoning': \"The unit of financial figures is explicitly mentioned multiple times in the text as 'millions', including in table headers and notes. This is confirmed by various citations from pages 38, 42, 43, 52, 53, 54, 56, 65, 71, 72, 73, 75, 77, 79, 80, and 82.\",\n",
       "   'citation': [{'page': 38,\n",
       "     'matching_text': '($ in millions, except per share data)'},\n",
       "    {'page': 42, 'matching_text': '($ in millions)'},\n",
       "    {'page': 43, 'matching_text': '($ in millions)'},\n",
       "    {'page': 52, 'matching_text': '(In millions, except per share data)'},\n",
       "    {'page': 53,\n",
       "     'matching_text': 'Consolidated Statements of Comprehensive Income (In millions)'},\n",
       "    {'page': 54,\n",
       "     'matching_text': 'Consolidated Balance Sheets (In millions, except par value)'},\n",
       "    {'page': 55, 'matching_text': '(In millions, except per share data)'},\n",
       "    {'page': 56,\n",
       "     'matching_text': 'Consolidated Statements of Cash Flows (In millions)'},\n",
       "    {'page': 65,\n",
       "     'matching_text': 'Year Ended<br/>Jan 26, 2025<br/>(In millions, except per share data)'},\n",
       "    {'page': 71, 'matching_text': '(In millions) | (In millions)'},\n",
       "    {'page': 72, 'matching_text': '(In millions)'}]},\n",
       "  'revenue': {'reasoning': 'The total revenue for fiscal year 2025 is extracted from multiple sources within the text, all confirming the same figure of $130,497 million. The revenue recognized for fiscal year 2025 is also noted as $4,607 million, which is a separate figure. However, the primary focus is on the total revenue figure, which is consistently cited.',\n",
       "   'citation': [{'page': 38,\n",
       "     'matching_text': 'Revenue for fiscal year 2025 was $130.5 billion'},\n",
       "    {'page': 41,\n",
       "     'matching_text': 'Total                | $ 130,497    | $ | 60,922'},\n",
       "    {'page': 52, 'matching_text': 'Revenue | $ 130,497'},\n",
       "    {'page': 78,\n",
       "     'matching_text': 'Revenue | $ 116,193 | $ 14,304 | $ - | $ 130,497'},\n",
       "    {'page': 79, 'matching_text': 'Total revenue | $ 130,497'},\n",
       "    {'page': 80, 'matching_text': 'Total revenue              | $ 130,497'}]}},\n",
       " 'usage': {'num_pages_extracted': 130,\n",
       "  'num_document_tokens': 105932,\n",
       "  'num_output_tokens': 31306}}"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "filing_info.extraction_metadata"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## What's Next?\n",
    "\n",
    "In this example, we built an Extraction Agent that is capable of citing it's sources from the document it's extracting data from, and reasoning about its reponse. To further customize and improve on the results, you can also try to customize the `system_prompt` in the `ExtractConfig`.\n",
    "\n",
    "#### Learn More\n",
    "\n",
    "- [LlamaExtract Documentation](https://docs.cloud.llamaindex.ai/llamaextract/getting_started)\n",
    "- [Example Notebooks](https://github.com/run-llama/llama_cloud_services/tree/main/examples/extract)"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3",
   "name": "python3"
  },
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
